import React, { useState, useEffect, useRef } from 'react';
import { Button, message, Spin, Modal, Icon } from 'antd';
import { connect } from 'umi';
import { router, Link } from 'umi';
import { remove } from 'lodash';
import AuthComponent from '@/utils/auth/AuthComponent';
import { customControlConfig } from '@/pages/WorkFlow/components/FormControls/formConfig/custom';
import { useRequest } from '@/hooks';
import { BasicSettingForm, FormControls, Process, AdvancedSetting } from './components';
import styles from './styles.less';
import { saveProcessHold } from './services';

const WorkFlow = ({ processName, dispatch, location }) => {
    const [loading, setLoading] = useState(false);
    const [stepCurrent, setStepCurrent] = useState('basicSetting');
    const [translateX, setTranslateX] = useState(0);
    const [visibleModal, setVisibleModal] = useState(false);
    const [processId, setProcessId] = useState(null);
    const [runProcessHoldParams, setRunProcessHoldParams] = useState('');
    const basicSettingRef = useRef();
    const processDesignRef = useRef();
    const advancedSettingRef = useRef();
    const formControlsRef = useRef();

    const { id, operation } = location.query;

    // 步骤切换
    const handleStepChange = current => {
        if (current !== stepCurrent) {
            setStepCurrent(current);
        }
    };
    // 步骤
    const steps = [
        { label: '基础设置', key: 'basicSetting' },
        { label: '表单设计', key: 'formDesign' },
        { label: '流程设计', key: 'processDesign' },
        { label: '高级设置', key: 'advancedSetting' }
    ];

    // 发布
    const handlePublish = () => {
        const p1 = basicSettingRef.current.handleUpdate();
        const p2 = formControlsRef.current.handleUpdate();
        const p3 = processDesignRef.current.handleUpdate();
        const p4 = advancedSettingRef.current.handleUpdate();

        Promise.all([p1, p2, p3, p4])
            .then(res => {
                // 如果是编辑同时带有套件，将套件的最新配置进行同步，已经作为条件的属性不修改
                if (id) {
                    res[1].formData = res[1].formData.map(item => {
                        let obj = item;
                        if (item.children) {
                            // 查询套件是否存在，存在则替换套件配置信息
                            const customComp = customControlConfig.find(subItem => subItem?.tag === item?.tag);
                            if (customComp) {
                                customComp.isUsed = obj.isUsed; // 如果已经作为条件不能修改
                                customComp.formId = obj.formId; // formId不能修改
                                customComp.applyType = obj.applyType; // 代发起离职类型不能改
                                customComp.children.forEach(sItem => {
                                    const isHasUsedItem = obj.children.find(
                                        x => x.formId === sItem.formId && x.isUsed === true
                                    );
                                    if (isHasUsedItem) {
                                        sItem.isUsed = isHasUsedItem.isUsed;
                                    }
                                });
                                obj = customComp;
                            }
                        }
                        return obj;
                    });
                }

                /** 处理新增组件、套件没处理权限的时候需要给一个默认权限值，发起人节点是编辑，其他节点是只读
                如果有删除的组件、套件也要更新节点权限 */

                // 将当前组件全部抽取为一维数组
                const compList = [];
                res[1].formData.forEach(item => {
                    if (item?.children) {
                        item.children.forEach(subItem => {
                            compList.push(subItem.formId);
                        });
                    } else {
                        compList.push(item.formId);
                    }
                });

                // 递归处理权限
                const formOperatesFn = (node, list) => {
                    const arr = node?.properties?.formOperates;
                    const formOperate = node?.type === 'start' ? 2 : 1; // 操作权限 0 隐藏 1 只读 2 可编辑
                    const obj = node;
                    if (arr) {
                        // 权限里面不存在表单列表的进行移除
                        remove(arr, item => list.findIndex(subItem => subItem === item.formId) === -1);

                        // 表单列表里面存在的但是不在权限里面的进行默认赋值

                        list.forEach(item => {
                            const ind = arr.findIndex(subItem => item === subItem.formId);
                            if (ind === -1) {
                                arr.push({ formId: item, formOperate });
                            }
                        });
                    }
                    if (node?.conditionNodes) {
                        node.conditionNodes.forEach(item => {
                            if (item?.conditionNodes) {
                                formOperatesFn(item, list);
                            }
                            if (item?.childNode) {
                                formOperatesFn(item.childNode, list);
                            }
                        });
                    }
                    if (node?.childNode) {
                        formOperatesFn(node.childNode, list);
                    }
                    return obj;
                };
                formOperatesFn(res[2].formData, compList);

                return res;
            })
            .then(res => {
                const param = {
                    processConfig: res[0].formData,
                    formJson: JSON.stringify(res[1].formData),
                    processJson: JSON.stringify(res[2].formData),
                    advancedSetting: res[3].formData
                };
                setLoading(true);
                dispatch({
                    type: 'workFlowModel/updataWorkFlow',
                    payload: param
                })
                    .then(result => {
                        if (result.code === 10000) {
                            setProcessId(result.data);
                            setVisibleModal(true);
                        } else if (result.code === 50034) {
                            // 这里处理暂存或者发布的时候，提示覆盖，然后弹出对话框，
                            // 并且新增参数sureCoverOtherHold:true,确定重新请求
                            Modal.confirm({
                                title: '存在其他暂存数据，是否发布？',
                                onOk() {
                                    setLoading(true);
                                    dispatch({
                                        type: 'workFlowModel/updataWorkFlow',
                                        payload: { ...param, sureCoverOtherHold: true }
                                    })
                                        .then(q => {
                                            const { code: codes, msg: msgs, data: datas } = q;
                                            if (codes === 10000) {
                                                setProcessId(datas);
                                                setVisibleModal(true);
                                            } else {
                                                message.error(msgs);
                                            }
                                        })
                                        .finally(() => {
                                            setLoading(false);
                                        });
                                },
                                onCancel() {
                                    console.log('Cancel');
                                }
                            });
                        } else {
                            message.error(result.msg);
                        }
                    })
                    .finally(() => {
                        setLoading(false);
                    });
                console.log('===>DATA', param);
            })
            .catch(err => {
                setStepCurrent(err.tabName);
                if (err.message) {
                    message.warning(err.message);
                }
            });
    };

    // 暂存
    const { run: runProcessHold, loading: processHoldLoading } = useRequest(
        params => {
            setRunProcessHoldParams(params);
            return saveProcessHold(params);
        },
        {
            manual: true,
            onSuccess: res => {
                const { code, msg } = res;
                if (code === 10000) {
                    message.success(msg);
                    history.push('/office/institutions/flowManage/formManager');
                } else if (code === 50034) {
                    // 这里处理暂存或者发布的时候，提示覆盖，然后弹出对话框，
                    // 并且新增参数sureCoverOtherHold:true,确定重新请求
                    Modal.confirm({
                        title: '存在其他暂存数据，是否覆盖？',
                        onOk() {
                            runProcessHold({ ...runProcessHoldParams, sureCoverOtherHold: true });
                        },
                        onCancel() {
                            console.log('Cancel');
                        }
                    });
                } else {
                    message.error(msg);
                }
            }
        }
    );
    const handleHold = () => {
        const p1 = basicSettingRef.current.handleUpdate('hold');
        const p2 = formControlsRef.current.handleUpdate('hold');
        const p3 = processDesignRef.current.handleUpdate('hold');
        const p4 = advancedSettingRef.current.handleUpdate('hold');

        Promise.all([p1, p2, p3, p4])
            .then(res => {
                const param = {
                    processConfig: {
                        ...res[0].formData,
                        includeSubCompany: Number(res[0].formData?.includeSubCompany)
                    },
                    formJson: JSON.stringify(res[1].formData),
                    processJson: JSON.stringify(res[2].formData),
                    advancedSetting: res[3].formData
                };
                runProcessHold(param);
            })
            .catch(err => {
                setStepCurrent(err.tabName);
                if (err.message) {
                    message.warning(err.message);
                }
            });
    };

    // 步骤切换样式
    useEffect(() => {
        setTranslateX(steps.findIndex(t => t.key === stepCurrent) * 100);
    }, [stepCurrent]);

    const fetchList = () => {
        setLoading(true);
        dispatch({
            type: 'workFlowModel/fetchWorkFlow',
            payload: id,
            callback: () => {
                setLoading(false);
            }
        });
    };

    const beforeunload = e => {
        const confirmationMessage = '您有流程正在设计，当前操作系统可能不会保存您所做的更改。'; // 并没有卵用
        (e || window.event).returnValue = confirmationMessage;
        return confirmationMessage;
    };

    // 继续编辑，如果当前处于编辑状态直接关闭 Modal 不进行跳转
    const handleContinueEdit = () => {
        setVisibleModal(false);
        history.push(`/office/institutions/flowManage/formDesign?id=${processId}&operation=edit`);
    };

    useEffect(() => {
        // 编辑情况下，初始化数据
        if (operation === 'edit') {
            fetchList();
        } else {
            dispatch({
                type: 'workFlowModel/initWorkFlowData'
            });
        }
        // 判断页面是否刷新
        window.addEventListener('beforeunload', beforeunload);

        return () => {
            dispatch({
                type: 'workFlowModel/initWorkFlowData'
            });
            window.removeEventListener('beforeunload', beforeunload);
        };
    }, [id]);

    return (
        <div className={styles.workFlowWrap}>
            <Spin spinning={loading}>
                <div className={styles.navBar}>
                    {/* navLeft */}
                    <div className={styles.navLeft}>
                        <div className={styles.navTitle}>{processName || '空模板'}</div>
                    </div>

                    {/* navCenter */}
                    <div className={styles.navCenter}>
                        <div className={styles.ghostStep} style={{ transform: `translateX(${translateX}%)` }}></div>
                        {steps.map((item, ind) => (
                            <div
                                key={item.key}
                                className={`${styles.stepItem} ${stepCurrent === item.key ? styles.active : ''}`}
                                onClick={() => handleStepChange(item.key)}
                            >
                                <span>{ind + 1}</span>
                                {item.label}
                            </div>
                        ))}
                    </div>

                    {/* navRight */}
                    <div className={styles.navRight}>
                        <Button
                            className={styles.buttonCancel}
                            onClick={() => {
                                history.push('/office/institutions/flowManage/formManager');
                            }}
                        >
                            取消
                        </Button>
                        <Button
                            loading={processHoldLoading}
                            className={styles.buttonCancel}
                            onClick={() => {
                                handleHold();
                            }}
                        >
                            暂存
                        </Button>

                        <AuthComponent code="office:workflow:template:deploy">
                            <Button
                                type="primary"
                                className={styles.buttonPublish}
                                onClick={() => {
                                    handlePublish();
                                }}
                            >
                                发布
                            </Button>
                        </AuthComponent>
                    </div>
                </div>

                {/* 对应组件 */}
                <div className={styles.navContent}>
                    <div style={{ display: stepCurrent === steps[0].key ? 'block' : 'none' }}>
                        <BasicSettingForm wrappedComponentRef={basicSettingRef} tabName={steps[0].key} id={id} />
                    </div>
                    <div style={{ display: stepCurrent === steps[1].key ? 'block' : 'none' }}>
                        <FormControls
                            wrappedComponentRef={formControlsRef}
                            tabName={steps[1].key}
                            location={location}
                        />
                    </div>
                    <div
                        style={{ display: stepCurrent === steps[2].key ? 'block' : 'none', backgroundColor: '#f0f2f5' }}
                    >
                        <Process wrappedComponentRef={processDesignRef} tabName={steps[2].key} />
                    </div>
                    <div style={{ display: stepCurrent === steps[3].key ? 'block' : 'none' }}>
                        <AdvancedSetting wrappedComponentRef={advancedSettingRef} tabName={steps[3].key} />
                    </div>
                </div>
            </Spin>
            <Modal
                width={424}
                visible={visibleModal}
                closable={false}
                footer={null}
                centered
                wrapClassName={styles.flowCreatedSuccessModal}
            >
                <div className={styles.modalContentBox}>
                    <div className={styles.boxLeft}>
                        <Icon type="check-circle" theme="filled" />
                    </div>
                    <div className={styles.boxRight}>
                        <p>[{processName}] 发布成功！</p>
                        <span>员工可以通过个人主页-我的流程进行提交</span>
                    </div>
                </div>
                <div className={styles.modalFooterBox}>
                    <Button onClick={handleContinueEdit}>继续编辑</Button>
                    <Button type="primary" onClick={() => setVisibleModal(false)}>
                        <Link to="/office/institutions/flowManage/formManager" replace>
                            完成
                        </Link>
                    </Button>
                </div>
            </Modal>
        </div>
    );
};

export default connect(({ workFlowModel }) => ({ processName: workFlowModel.basicData.processName }))(WorkFlow);
